﻿using System;
using System.Collections.Generic;
using com.yoozoo.gta.Gameplay.RTS;
using Gameplay.PVE.Utils;
using UnityEngine;
using Yoozoo.Gameplay.RTS.Proto;
using Random = System.Random;

namespace Yoozoo.Gameplay.RTS
{
    public enum E_BattleTextType
    {
        NormalText = 1,
        DamageText = 2,
        HealText = 3
    }
    public enum ERtsSkillState
    {
        NotPlay = 1,
        Playing = 2,
        End = 3,
        AttackRoundStart = 4,
        AttackRoundEnd = 5,
    }
    public static class MarchHelper
    {
        public const int TeamSelf = 0;
        public const int TeamFriend = 1;
        public const int TeamEnemy = 2;
        public const int TeamOther = 3;
        public const int TeamRedName = 4; // 红名玩家
        public static float attack_range_1 = 0.3f;
        public static float chaseAttackOffset = 0.3f;//默认值 会从lua传来赋值
        /// <summary>
        /// 标准视角下的缩放，hud等缩放以此缩放为标准进行不同lod层级下的缩放计算
        /// </summary>
        public const float standardScale = 3.35f;

        public static float[] LODHeight = new float[]{
            5.5f,
            5.5f,
            12f,
            22.5f,
            35.3333f,
            80f,
        };

        public static float GetLod0Scale(int lodLevel, float lodPercent)
        {
            // LOD1: 0.001 => Lod0 20%
            // LOD2: 0.003 => Lod0 50%
            // LOD3: 0.005 => Lod2 0%
            float totalLodLevel = lodLevel * 100f + lodPercent;
            float progress = Mathf.Clamp01((totalLodLevel - 20f) / 200f);
            return Mathf.Lerp(0.0015f, 0.0075f, progress);
        }

        public static float GetLod1Scale(int lodLevel, float lodPercent)
        {
            // LOD3阶段，对应沙盒的 LOD2 0% 到 LOD4 100%
            // scale: 0.005 => 0.07
            float totalLodLevel = lodLevel * 100f + lodPercent;
            float progress = Mathf.Clamp01((totalLodLevel - 200f) / 400f);
            return Mathf.Lerp(0.005f, 0.07f, progress);
        }

        public static float GetLod1ScaleByHeight(int lodLevel, float cameraHight)
        {
            var height = LODHeight[2];
            return 0.005f * (cameraHight / height);
        }

        public static int GetMarchLodLevel(int lodLevel, float lodPercent)
        {
            int marchLodLevel = 0;
            for (int i = 0; i < WorldEntry.MarchLodLevelCount; i++)
            {
                marchLodLevel = i;
                int currentLodLevel = WorldEntry.MarchLodLevels[i];
                float currentLodPercent = WorldEntry.MarchLodPercents[i];
                if (lodLevel < currentLodLevel)
                    break;

                if (lodLevel == currentLodLevel && lodPercent <= currentLodPercent)
                    break;
            }

            return marchLodLevel+1;  // 因为是从0开始的；而lod0已被废弃
        }
        // public const int TeamSelf = 0;
        // public const int TeamFriend = 1;
        // public const int TeamEnemy = 2;
        // public const int TeamOther = 3;
        public static  Color[] TeamColors;
        public static Color[] TeamTxtColors;
        public static Color[] ShadowColors;
        public static Color[] BattleDirectionColor = new Color[] {
            new Color(49/255f,1,35/255f),
            new Color(255/255f,22/255f,14/255f),
        };

        public static Color[] RenownTxtColors = new Color[]
        {
            new Color(0.745f, 0.792f, 0.807f),
            new Color(0.435f, 1, 0.521f),
            new Color(0.423f, 0.643f, 1),
            new Color(0.701f, 0.396f, 1),
            new Color(1, 0.65f, 0.231f),
            new Color(0.972f, 0.282f, 0.364f),
        };
        //     = new[]
        // {
        //     new Color(148 / 255f, 255 / 255f, 114 / 255f).linear,    //TeamSelf = 0;
        //     new Color(109 / 255f, 216 / 255f, 255 / 255f).linear,    //TeamFriend = 1;
        //     new Color(248 / 255f, 113 / 255f, 86/ 255f).linear,      //TeamEnemy = 2;
        //     new Color(255f / 255f, 245 / 255f, 245/ 255f).linear,   //TeamOther = 3;
        // };


        public static void Log(object content)
        {
            UnityEngine.Debug.LogError(TimeUtils.GetClientTickTime().ToString("f2")+" " + content);
        }

        public static int CrossingGateFormationId = 8991;
        public static int CrossingGateAssemblyFormationId = 8992;
        public static int TradeTruckAttackerFormationId = 8994;
        public static int TradeTruckFormationId = 8993;

        private static Dictionary<int, Vector3> arenaPositions = new Dictionary<int, Vector3>
        {
            [1] = new Vector3(-1.3f,0,1.85f),
            [2] = new Vector3(-1.3f,0,0.65f),
            [3] = new Vector3(-1.3f,0,-0.65f),
            [4] = new Vector3(-1.3f,0,-1.85f),
            [5] = new Vector3(-2.6f,0,1.85f),
            [6] = new Vector3(-2.6f,0,0.65f),
            [7] = new Vector3(-2.6f,0,-0.65f),
            [8] = new Vector3(-2.6f,0,-1.85f),
            
            [11] = new Vector3(1.3f,0,1.85f),
            [12] = new Vector3(1.3f,0,0.65f),
            [13] = new Vector3(1.3f,0,-0.65f),
            [14] = new Vector3(1.3f,0,-1.85f),
            [15] = new Vector3(2.6f,0,1.85f),
            [16] = new Vector3(2.6f,0,0.65f),
            [17] = new Vector3(2.6f,0,-0.65f),
            [18] = new Vector3(2.6f,0,-1.85f),
        };
        
        private static Dictionary<int, Vector3> arenaStartPositions = new Dictionary<int, Vector3>
        {
            [21] = new Vector3(-1.3f,0,1.85f),
            [22] = new Vector3(-1.3f,0,0.65f),
            [23] = new Vector3(-1.3f,0,-0.65f),
            [24] = new Vector3(-1.3f,0,-1.85f),
            [11] = new Vector3(-2.6f,0,1.85f),
            [12] = new Vector3(-2.6f,0,0.65f),
            [13] = new Vector3(-2.6f,0,-0.65f),
            [14] = new Vector3(-2.6f,0,-1.85f),
        };
        private static Dictionary<int, Vector3> radarArenaStartPositions = new Dictionary<int, Vector3>
        {
            [1] = new Vector3(0.663f, 0, -1.013f),
            [2] = new Vector3(-0.095f, 0, -1.771f),
            [3] = new Vector3(1.96f, 0, -1.39f),
            [4] = new Vector3(1.177f, 0, -2.173f),
            [5] = new Vector3(0.4269999f, 0, -2.923f),
            [21] = new Vector3(-0.826f, 0, 0.5350001f),
            [22] = new Vector3(-1.584f, 0, -0.223f),
            [23] = new Vector3(-1.348f, 0, 1.687f),
            [24] = new Vector3(-2.098f, 0, 0.937f),
            [25] = new Vector3(-2.881f, 0, 0.154f),
        };

        public static void SetArenaInitPosition(int id, float x, float z,int type)
        {
            if (type == 1)
            {
                arenaStartPositions[id] = new Vector3(x, 0, z);
            }
            else
            {
                radarArenaStartPositions[id] = new Vector3(x, 0, z);
            }
        }

        private static Quaternion arenaQuaternion = Quaternion.AngleAxis(45, Vector3.up);
        public static Vector3 TransformArenaPosition(Vector3 originPosition,bool needReverse = false)
        {
            if (RtsArenaManager.Instance.IsExpeditionReport())
            {
                return originPosition;
            }
            if (needReverse)
            {
                originPosition = new Vector3(-originPosition.x,originPosition.y,originPosition.z);
            }
            return arenaQuaternion * originPosition;
        }

        public static com.youzu.warh.protocol.Coordinate TransformArenaCoordinate(
            com.youzu.warh.protocol.Coordinate originCoordinate, bool needReverse = false)
        {
            if (RtsArenaManager.Instance.IsExpeditionReport())
            {
                return originCoordinate;
            }
            var position = new Vector3(originCoordinate.xAxis, 0, originCoordinate.zAxis);
            position = TransformArenaPosition(position, needReverse);
            return position.ToProtoCoordinate();
        }
        
        public static Vector3 GetArenaStartPositionById(long id)
        {
            var cameraCenter = RtsArenaManager.Instance.CenterPosition;
            if (arenaPositions.TryGetValue((int)id, out var position))
            {
                position = Quaternion.AngleAxis(45, Vector3.up) * position;
                //Debug.LogError(id + " "  + position);
                return position + cameraCenter;
            }

            return Vector3.zero;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="posId"></param>
        /// <param name="camp"></param>
        /// <param name="type">0是竞技场 1是雷达竞技场</param>
        /// <returns></returns>
        public static Vector3 GetArenaPositionByPosIdAndCamp(int posId,int camp,int type)
        {
            if (type == 0)
            {
                if (arenaStartPositions.TryGetValue(posId, out var position))
                {
                    if (camp != 0)
                    {
                        position.x = -position.x;
                    }
                    position = TransformArenaPosition(position);
                    return position;
                }
                return Vector3.zero;
            }
            else if (type == 1)
            {
                //if (camp == 2)
                //{
                //    posId = camp * 10 + posId;
                //}
                if (radarArenaStartPositions.TryGetValue(posId, out var position))
                {
                    if (camp == 2)
                    {
                        position.x = -position.x;
                    }
                    position = TransformArenaPosition(position);
                    return position;
                }
                return Vector3.zero;
            }
            else
            {
                return RtsArenaManager.Instance.GetExpeditionPosition(posId);
            }
        }
        

        public static Coordinate ToCoordinate(this Vector3 vector3)
        {
            return new Coordinate
            {
                xAxis = vector3.x,
                zAxis = vector3.z,
            };
        }

        public static com.youzu.warh.protocol.Coordinate ToProtoCoordinate(this Vector3 vector3)
        {
            return new com.youzu.warh.protocol.Coordinate
            {
                xAxis = vector3.x,
                zAxis = vector3.z,
            };
        }

        public static bool ShowRtsSkillEffect()
        {
            var marchManager = MarchManager.Instance;
            if (marchManager != null)
            {
                return marchManager.marchContext.MarchLodLevel < WorldEntry.MaxShowMarchLodLevel;
            }
            return false;
        }

        public static bool IsPveAssembleDismissed(RtsServerInfo rtsServerInfo)
        {
            if (rtsServerInfo.leavePveAssemblyId > 0)
            {
                return true;
            }
            return false;
        }

        public static bool IsPveAssembleTarget(MarchEntity marchEntity)
        {
            return marchEntity.TargetCoordinateType == TargetCoordinateType.POLICE_OFFICE_16 ||
                   (marchEntity.TargetCoordinateType == TargetCoordinateType.MONSTER_4 && marchEntity.RtsServerInfo.npcType == RtsNpcType.NPC_BELT_MONSTER);
        }

        public static Vector3 GetRandomForward()
        {
            var angle = UnityEngine.Random.Range(0, 360f);
            var rad = angle * Mathf.Deg2Rad;
            return new Vector3(Mathf.Cos(rad), 0, Mathf.Sin(rad));
        }

        public static bool fixTradeTruckPath = true;
        
        //根据车道修改路径点
        public static void GenerateTradeTruckCoordinateAndPathList(RtsServerInfo serverInfo)
        {
            if (!fixTradeTruckPath)
            {
                return;
            }
            //判断是否有路点
            var path = serverInfo.pathList;
            if (path == null || path.Length < 2)
            {
                return;
            }

            var offsetIndex = serverInfo.tid % 3;
            float offsetValue = 0.1f;
            if (offsetIndex == 1)
            {
                offsetValue = 0.3f;
            }
            else if (offsetIndex == 2)
            {
                offsetValue = 0.5f;
            }
            //根据每条路径点，进行偏移
            var realOffset = Vector3.zero;
            Coordinate lastPoint = path[0];
            var lastPathDirection = Vector3.zero;
            for (int i = 0; i < path.Length - 1; i++)
            {
                var start = lastPoint.ToVector3();
                var end = path[i + 1].ToVector3();
                var direction = (end - start).normalized;
                lastPoint = path[i + 1];
                if (i == 0)
                {
                    realOffset = Quaternion.AngleAxis(-90, Vector3.up) * direction * offsetValue;
                    serverInfo.coordinate.xAxis += realOffset.x;
                    serverInfo.coordinate.zAxis += realOffset.z;
                }
                else
                {
                    //计算角平分线
                    var angle =  PveUtils.GetAngle(lastPathDirection,direction);
                    if (angle < 0)
                    {
                        angle += 360;
                    }
                    angle /= 2;
                    var realDirection = Quaternion.AngleAxis(-angle, Vector3.up) * lastPathDirection;
                    realOffset = realDirection * offsetValue;
                }
                lastPathDirection = direction;
                path[i] = (start + realOffset).ToCoordinate();
            }

            var endPoint = path[^1].ToVector3();
            path[^1] = (endPoint + Quaternion.AngleAxis(-90, Vector3.up) * lastPathDirection * offsetValue).ToCoordinate();
        }

        //0蓝，1绿，2红，3紫，4橙
        public static int GetTruckTeamColorByColor(int configId)
        {
            switch (configId)
            {
                case 2:
                    return 1;
                case 3:
                    return 0;
                case 4:
                    return 3;
                case 5:
                    return 4;
                case 6:
                    return 2;
                default:
                    return 0;
            }
        }

        public static int TruckEffect = 1017; // 货车着火特效
        public static int TrainEffect = 1018; // 列车着火特效
    }
}
